package com.brillilab.starter.controller.aio.method;

import com.brillilab.common.constant.ResultEnum;
import com.brillilab.common.entity.Id;
import com.brillilab.common.entity.ResponseVo;
import com.brillilab.domain.enums.common.BoolEnum;
import com.brillilab.domain.enums.method.MethodSourceEnum;
import com.brillilab.domain.po.method.Method;
import com.brillilab.domain.po.method.MethodType;
import com.brillilab.domain.po.method.MethodWithFirstType;
import com.brillilab.domain.vo.method.*;
import com.brillilab.domain.vo.user.UserInfoVo;
import com.brillilab.service.core.method.IMethodService;
import com.brillilab.service.core.method.IMethodTypeService;
import com.brillilab.service.logic.method.MethodLogic;
import com.brillilab.service.logic.method.MethodTypeLogic;
import com.brillilab.service.logic.user.UsersLogic;
import com.brillilab.starter.aspect.AspectLog;
import com.brillilab.starter.constant.StarterConstant;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;


import javax.annotation.Resource;
import java.util.List;

/**
 * @author wuzhiyu
 * @Title: MethodController
 * @ProjectName brill_lab
 * @Description: TODO
 * @date 2019/2/2110:03
 */
@RestController
@RequestMapping("/api/method")
public class MethodController {

    @Resource
    private UsersLogic usersLogic;
    @Resource
    private MethodLogic methodLogic;
    @Resource
    private IMethodService methodService;
    @Resource
    private IMethodTypeService methodTypeService;

    /**
     * @return com.brillilab.common.entity.ResponseVo
     * @Description: 导入，手动 新建方法
     * @Params: [newMethod, token]
     * @author wuzhiyu
     * @date 2019/2/26 16:35
     */
    @AspectLog
    @PostMapping("/new")
    public ResponseVo newMethod(@RequestBody NewMethod newMethod, @RequestHeader(value = StarterConstant.TOKEN) String token) {
        Assert.notNull(newMethod, "参数缺失");
        Assert.notNull(newMethod.getMethodTypeId(), "参数缺失");
        Assert.isTrue(MethodSourceEnum.CREATE.getSourceType().equals(newMethod.getFromType()) || (MethodSourceEnum.IMPORT.getSourceType().equals(newMethod.getFromType()) && newMethod.getInitMethodId() != null), "来源类型错误");
        UserInfoVo user = usersLogic.getUserByToken(token);
        return ResponseVo.successMap("id", methodLogic.addNewMethod(newMethod, user));
    }

    /**
     * @return com.brillilab.common.entity.ResponseVo
     * @Description: 获取方法详情
     * @Params: [id, token]
     * @author wuzhiyu
     * @date 2019/2/26 16:35
     */
    @GetMapping("/detail")
    public ResponseVo detail(Long id, Integer  isDelete, @RequestHeader(value = StarterConstant.TOKEN) String token) {
        Assert.notNull(id, "参数缺失");
        UserInfoVo user = usersLogic.getUserByToken(token);
        MethodDetail methodDetail = methodLogic.getMethodDetail(id, BoolEnum.getEnum(isDelete), user.getLabId());
        return ResponseVo.success(methodDetail);
    }

    /**
     * @return com.brillilab.common.entity.ResponseVo
     * @Description: 根据第三级方法类型获取一个推荐方法
     * @Params: [thirdTypeId]
     * @author wuzhiyu
     * @date 2019/2/26 16:36
     */
    @GetMapping("/referRecommondOne")
    public ResponseVo referRecommondOne(Long thirdTypeId) {
        Assert.notNull(thirdTypeId, "参数缺失");
        ReferMethodListItem item = methodService.getReferRecommondOneByThirdTypeId(thirdTypeId);
        return ResponseVo.success(item);
    }

    /**
     * @return com.brillilab.common.entity.ResponseVo
     * @Description: 推荐方法列表
     * @Params: [thirdTypeId, searchName]
     * @author wuzhiyu
     * @date 2019/2/26 16:36
     */
    @GetMapping("/referList")
    public ResponseVo referList(Integer pageIndex, Integer rows, Long secondTypeId, String searchName) {
        pageIndex = pageIndex == null ? 1 : pageIndex;
        rows = rows == null ? 10 : rows;
        return ResponseVo.success(methodLogic.getReferList(secondTypeId, searchName, pageIndex, rows , false));
    }

    /**
     * @description 试剂参考方法列表
     * @author WuMengaho
     * @params [pageIndex,rows,secondTypeId,searchName]
     * @return com.brillilab.common.entity.ResponseVo
     */
    @GetMapping("/kitReferList")
    public ResponseVo kitReferList(Integer pageIndex, Integer rows, Long secondTypeId, String searchName) {
        pageIndex = pageIndex == null ? 1 : pageIndex;
        rows = rows == null ? 10 : rows;
        return ResponseVo.success(methodLogic.getReferList(secondTypeId, searchName, pageIndex, rows , true));
    }

    /**
     * @return com.brillilab.common.entity.ResponseVo
     * @Description: 判断当前用户已有同类型的方法和成员分享的方法是否同源，同源直接保存，不同源判断名称方法是否相同，相同则提示修改
     * @Params: [typeName, methodName, token]
     * @author wuzhiyu
     * @date 2019/2/26 16:36
     */
    @GetMapping("/sameMethodExist")
    public ResponseVo sameMethodExist(Long otherMethodId, @RequestHeader(value = StarterConstant.TOKEN) String token) {
        Assert.notNull(otherMethodId, "参数缺失");
        UserInfoVo user = usersLogic.getUserByToken(token);
        return ResponseVo.success(methodLogic.sameMethodExist(otherMethodId, user));
    }

    /**
     * @return com.brillilab.common.entity.ResponseVo
     * @Description: 根据第三级方法类型获取列表
     * @Params: [thirdTypeId, token]
     * @author wuzhiyu
     * @date 2019/2/26 16:37
     */
    @GetMapping("/methodListByTypeId")
    public ResponseVo methodListByTypeId(Long thirdTypeId, @RequestHeader(value = StarterConstant.TOKEN) String token) {
        Assert.notNull(thirdTypeId, "参数缺失");
        UserInfoVo user = usersLogic.getUserByToken(token);
        return ResponseVo.success(methodLogic.methodListByTypeId(thirdTypeId, user));
    }

    /**
     * @return com.brillilab.common.entity.ResponseVo
     * @Description: 设为当前默认版本方法
     * @Params: [methodIdList, token]
     * @author wuzhiyu
     * @date 2019/2/26 16:38
     */
    @PostMapping("/resetToCurrent")
    public ResponseVo resetToCurrent(@RequestBody Id methodId, @RequestHeader(value = StarterConstant.TOKEN) String token) {
        Assert.notNull(methodId, "参数缺失");
        Assert.notNull(methodId.getId(), "参数缺失");
        UserInfoVo user = usersLogic.getUserByToken(token);
        return ResponseVo.success(methodLogic.resetToCurrent(methodId.getId(), user));
    }

    /**
     * @return com.brillilab.common.entity.ResponseVo
     * @Description: 编辑生成新版本
     * @Params: [newMethod, token]
     * @author wuzhiyu
     * @date 2019/2/26 16:39
     */
    @AspectLog
    @PostMapping("/newVersion")
    public ResponseVo newVersion(@RequestBody NewMethod newMethod, @RequestHeader(value = StarterConstant.TOKEN) String token) {
        Assert.notNull(newMethod, "参数缺失");
        Assert.notNull(newMethod.getInitMethodId(), "参数缺失");
        UserInfoVo user = usersLogic.getUserByToken(token);
        return ResponseVo.successMap("id",methodLogic.addNewVersion(newMethod, user));
    }

    /**
     * @return com.brillilab.common.entity.ResponseVo
     * @Description: 获取版本列表
     * @Params: [methodIdList, token]
     * @author wuzhiyu
     * @date 2019/2/27 9:38
     */
    @GetMapping("/versionList")
    public ResponseVo versionList(Long methodId, @RequestHeader(value = StarterConstant.TOKEN) String token) {
        Assert.notNull(methodId, "参数缺失");
        UserInfoVo user = usersLogic.getUserByToken(token);
        return ResponseVo.success(methodLogic.listVersionList(methodId, user));
    }

    @AspectLog
    @PostMapping("/update")
    public ResponseVo update(@RequestBody NewMethod newMethod, @RequestHeader(value = StarterConstant.TOKEN) String token) {
        Assert.notNull(newMethod, "数据为空");
        Assert.notNull(newMethod.getId(), "数据为空");
        UserInfoVo user = usersLogic.getUserByToken(token);
        return ResponseVo.successMap("id",methodLogic.updateOrNewVersion(newMethod, user));
    }

    @GetMapping("/compare")
    public ResponseVo compare(Long methodId, boolean isPrevious, @RequestHeader(value = StarterConstant.TOKEN) String token) {
        Assert.notNull(methodId, "数据为空");
        UserInfoVo user = usersLogic.getUserByToken(token);
        return ResponseVo.success(methodLogic.versionDiff(methodId, isPrevious, user));
    }
    @DeleteMapping("/delete")
    public ResponseVo delete(Long methodId,@RequestHeader(value = StarterConstant.TOKEN) String token)
    {
        Assert.notNull(methodId,"参数缺失");
        UserInfoVo user= usersLogic.getUserByToken(token);
        return ResponseVo.success(methodLogic.delete(methodId,user));
    }

    @GetMapping("/sameSourceCompare")
    public ResponseVo sameSourceCompare(Long methodId,Long otherMethodId, @RequestHeader(value = StarterConstant.TOKEN) String token){
        Assert.notNull(methodId,"参数缺失");
        Assert.notNull(otherMethodId,"参数缺失");
        UserInfoVo user = usersLogic.getUserByToken(token);
        return ResponseVo.success(methodLogic.sameSourceDiff(methodId,otherMethodId,user));
    }

    @GetMapping("/sameNameAndType")
    public ResponseVo sameNameAndType(Long thirdTypeId,String methodName, @RequestHeader(value = StarterConstant.TOKEN) String token){
        Assert.notNull(thirdTypeId,"参数缺失");
        Assert.isTrue(!StringUtils.isEmpty(methodName),"参数缺失");
        UserInfoVo user = usersLogic.getUserByToken(token);
        return ResponseVo.success(methodLogic.sameNameAndType(thirdTypeId,methodName,user));
    }

    @AspectLog
    @PostMapping("/convertMethod")
    public ResponseVo convertMethod(@RequestBody MethodConvertText text,@RequestHeader(value = StarterConstant.TOKEN) String token){
        Assert.isTrue(text!=null&&!StringUtils.isEmpty(text.getText()));
        List<MethodPhaseDetail> list= methodLogic.convertMethod(text.getText());
        return ResponseVo.success(list);
    }

    @GetMapping("/deleteList")
    public ResponseVo deleteList(@RequestHeader(value = StarterConstant.TOKEN) String token){
        UserInfoVo user = usersLogic.getUserByToken(token);
        return ResponseVo.success(methodLogic.getDeleteList(user.getId()));
    }
    @GetMapping("/restore")
    public ResponseVo restore(Long methodId,@RequestHeader(value = StarterConstant.TOKEN) String token){
        Assert.notNull(methodId,ResultEnum.REQUEST_PARAM_LACK.getMessage());
        UserInfoVo user = usersLogic.getUserByToken(token);
        return ResponseVo.success(methodLogic.restoreMethod(methodId,user.getId()));
    }

    @GetMapping("/import")
    public ResponseVo methodImport(Long methodId,Long globalKitId,@RequestHeader(value = StarterConstant.TOKEN) String token){
        Assert.notNull(methodId,ResultEnum.REQUEST_PARAM_LACK.getMessage());
        UserInfoVo user = usersLogic.getUserByToken(token);
        Method newMethod = methodLogic.importMethod(methodId, globalKitId, user);
        MethodWithFirstType m =new MethodWithFirstType();
        BeanUtils.copyProperties(newMethod,m);
        MethodType type = methodTypeService.getMethodTypeById(newMethod.getMethodTypeId());
        m.setFirstTypeId(type.getFirstId());
        return ResponseVo.success(m);
    }
}
